﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace 异步编程基础_05
{
    class Juice { }
    class Egg { }
    class Bacon { }
    class Toast { }
    class Coffee { }

    class Program
    {
        static void Main(string[] args)
        {
            Coffee cup = PourCoffee();
            Console.WriteLine("coffee is ready");
            FunctionAsync().Wait();
            //            Task.Run(FunctionAsync).Wait();
            Juice oj = PourOJ();
            Console.WriteLine("oj is ready");
            Console.WriteLine("Breakfast is ready");
        }

        private static async Task FunctionAsync()
        {
            var eggsTask = FryEggsAsync(2);
            var baconTask = FryBaconAsync(3);
            var toastTask = MakeToastWithButterAndJamAsync(2);
            List<Task> breakfastTasks = new List<Task> { eggsTask, baconTask, toastTask };
            while (breakfastTasks.Count > 0)
            {
                Task finishedTask = await Task.WhenAny(breakfastTasks);
                if (finishedTask == eggsTask)
                {
                    Console.WriteLine("eggs are ready");
                }
                else if (finishedTask == baconTask)
                {
                    Console.WriteLine("bacon are ready");
                }
                else if (finishedTask == toastTask)
                {
                    Console.WriteLine("toast are ready");
                }
                breakfastTasks.Remove(finishedTask);
            }
        }
        static async Task<Toast> MakeToastWithButterAndJamAsync(int number)
        {
            var toast = await ToastBreadAsync(number);
            ApplyButter((Toast)toast);
            ApplyJam((Toast)toast);
            return (Toast)toast;
        }
        private static Juice PourOJ()
        {
            Console.WriteLine("Pouring orange juice");
            return new Juice();
        }

        private static void ApplyJam(Toast toast)
        {
            Console.WriteLine("Putting jam on the toast");
        }

        private static void ApplyButter(Toast toast)
        {
            Console.WriteLine("Putting butter on the toast");
        }

        private static async Task<object> ToastBreadAsync(int slices)
        {
            for (int slice = 0; slice < slices; slices++)
            {
                Console.WriteLine("Putting a slice of bread in the toaster");
            }
            Console.WriteLine("Start toasting......");
            await Task.Delay(3000);
            Console.WriteLine("Remove toast from toaster");
            return new Toast();
        }
        private static async Task<Bacon> FryBaconAsync(int slices)
        {
            Console.WriteLine("Putting {0} slices of bacon in the pan", slices);
            Console.WriteLine("cooking first side of bacon......");
            await Task.Delay(3000);
            for (int slice = 0; slice < slices; slice++)
            {
                Console.WriteLine("filpping a slice of bacon");
            }
            Console.WriteLine("cooking the second side of bacon......");
            await Task.Delay(3000);
            Console.WriteLine("Put bacon on plate");
            return new Bacon();
        }
        private static async Task<Egg> FryEggsAsync(int howmany)
        {
            Console.WriteLine("Warming the egg pan......");
            await Task.Delay(3000);
            Console.WriteLine("cracking {0} eggs", howmany);
            Console.WriteLine("cooking the eggs......");
            await Task.Delay(3000);
            Console.WriteLine("Put eggs on plate");
            return new Egg();
        }
        private static Coffee PourCoffee()
        {
            Console.WriteLine("Putting coffee");
            return new Coffee();
        }
    }
}